%% Calibration and solution of the model
% by IMF Institute for Capacity Development - Course on Monetary and Exchange Rate Policies

%% Clear the workspace
close all; 
clear all;

%% Typical parameter values to be used in calibrations
%% ...
% 1. Aggregate demand equation
%% ...
% lgdp_gap = a1*lgdp_gap{-1} - a2*mci + a3*lx_gdp_gap + shk_lgdp_gap
%% ...
% mci = a4*rr_gap + (1-a4)*(-lz_gap);
%% ...
% a1 - Output persistence varies between 0.1 (extremely flexible) and 0.95
% (extremely persistent)
p.a1 = 0.8;
%% ...
% a2 - Policy passthrough (impact of monetary policy on real economy) varies
% between 0.1 (relatively low impact) to 0.5 (strong impact)
p.a2 = 0.2;
%% ...
% a3 - External demand impact varies between 0.1 and 0.6
p.a3 = 0.5;
%% ...
% a4 - Weight of real interest rate and real exchange rate in monetary
% conditions a4 varies from 0.3 to 0.8
p.a4 = 0.6;
%% ...
% 2. Aggregate supply equation (Phillips curve)
%% ...
% dot_cpi =  b1*dot_cpi{-1} + (1-b1)*dot_cpi{+1}) + b2*rmc + shk_dot_cpi
%% ...
% rmc = b3*lgdp_gap + (1-b3)*lz_gap;
%% ...
p.b1 = 0.6;
%% ...
% Inflation persistence; b1 varies between 0.4 (low persistence) to 0.9
% (high persistence)

%policy passthrough (impact of output gap on inflation); b2 varies between 0.1 
%(a flat Phillips curve and high sacrifice ratio) to 0.5 (steep Phillips
%curve and low sacrifice ratio)
p.b2 = 0.2;

%(1-b3) is a ratio of imported goods in firms marginal costs; b3 varies between 0.1 for
%highly closed economy to 0.3 for an open economy
p.b3 = 0.5;

%% 4. Uncovered Interest Rate Parity
% ls = (1-e1)*ls{+1} + e1*(ls{-1} + 2/4*(target - ss_dot_x_cpi + dot_z_eq)) + (- rn + x_rn + prem)/4 + shk_ls;

% UIP with partly backward-looking element 

% or

% ls = e1*ls_tar + (1-e1)*(ls{+1} + ( - rn + x_rn + prem)/4) + shk_ls;

%central bank manages the exchange rate to meet its inflation objective;

%e1 captures for exchange rate persistency or central bank's FOREX interventions; e1 varies between zero to
%0.9 (very high control of the exchange rate); 
p.e1 = 0.5;

%% 5. Monetary policy rule
% rn = f1*rn{-1} + (1-f1)*(rn_neutral + f2*(dot_cpi{+1} - target) + f3*lgdp_gap) + shk_rn;

%policy persistence; f1 varies from zero (no persistence in policy setting)
%to 0.8 ("wait and see" monetary policy)
p.f1 = 0.7;

%policy reactiveness (weight put on inflation by policy maker); f2 has no
%upper limit but must be always higher then zero (Taylor principle)
p.f2 = 0.5;

%policy reactiveness (weight put on output gap by policy maker); f3 has no
%upper limit but must be always higher then zero
p.f3 = 0.5;

% in case of imperfect control of the domestic money market (use only if the central bank
% stabilieses exchange rate by interventions)

% rn = g1*(4*(ls{+1} - ls) + x_rn + prem) + (1-g1)*(f1*rn{-1} + (1-f1)*(rn_neutral + f2*(dot_cpi{+1} - target)) + shk_rn);

%degree to which the central bank does not control domestic money market
p.g1 = 0;

%% 7. Speed of convergence of last observed trend value to it calibrated value.
% Used for persistent shock in risk premium, trend in GDP, real interest rate, real exchange rate,
% foreign real interest rate and exchange rate target
p.h0 = 0.5;
p.h1 = 0.5;
p.h2 = 0.5;
p.h3 = 0.5;
p.t1 = 0.95;

%% The inflation target and observed economic trends

% Domestic inflation target
p.target_ss = 3;
% Foreign trend inflation
p.ss_dot_x_cpi = 2;
% Calibrated trend level of domestic real interest rate 
p.ss_rr_eq = 2;
% Calibrated trend change in the real exchange rate (negative number is 
% real appreciation);
p.ss_dot_z_eq = -2;
% Calibrated trend growth of potential output 
p.ss_dot_gdp_eq = 6;
% Calibrated trend level of foreign real interest rate
p.ss_x_rr_eq = 0.5;

%% Model solving--a brief description of commands
% Command 'model' reads the text file 'model.mod' (contains the model's
% equations), assigns the parameters and trend values preset in the database
% 'p' (see readmodel) and transforms the model for the matrix algebra. 
% Transformed model is written in the object 'm'.
p.nonlinear = false;
m = model('model.model','linear=',true,'assign',p);

% Command 'solve' takes the model saved in object 'm' and solves the model
% for its reduced form (Blanchard-Kahn algorithm). The reduced form is  
% written back in the object 'm'   
m = solve(m);

% Command 'sstate' takes the solved model in object 'm', calculates the model's
% steady-state and writes everything back in the object 'm'. Typing 'mss' in
% Matlab command window provides the steady-state values.
m = sstate(m,'growth',true,'MaxFunEvals',2000);
mss = get(m,'sstate');
p = dbextend(p,mss);

% Solve model as non-linear using steady-state calculated for linear one
p.nonlinear = true;
m = model('model.model','linear=',false,'assign',p);
m = solve(m);

%% Check steady state
[flag,discrep,eqtn] = chksstate(m);

if ~flag
  error('Equation fails to hold in steady state: "%s"\n', eqtn{:});
end

% Command 'save' saves the object 'm' in the database 'model.mat'
% (current directory is used as default for saving)
% !! so far doesn't work in Octave
%save('model.mat','m');
